package com.ruoyi.project.common;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.config.RuoYiConfig;
import com.ruoyi.framework.config.ServerConfig;
import com.ruoyi.framework.web.domain.AjaxResult;

/**
 * 通用请求处理
 *
 * @author ruoyi
 */
@Controller
@RequestMapping("/common")
public class CommonController
{
    private static final Logger log = LoggerFactory.getLogger(CommonController.class);

    @Autowired
    private ServerConfig serverConfig;

    private static final String FILE_DELIMETER = ",";

    /**
     * 通用下载请求
     *
     * @param fileName 文件名称
     * @param delete 是否删除
     */
    @GetMapping("/download")
    public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
    {
        try
        {
            if (!FileUtils.checkAllowDownload(fileName))
            {
                throw new Exception(StringUtils.format("文件名称({})非法，不允许下载。 ", fileName));
            }
            String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
            String filePath = RuoYiConfig.getDownloadPath() + fileName;

            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, realFileName);
            FileUtils.writeBytes(filePath, response.getOutputStream());
            if (delete)
            {
                FileUtils.deleteFile(filePath);
            }
        }
        catch (Exception e)
        {
            log.error("下载文件失败", e);
        }
    }

    /**
     * 通用上传请求（单个）
     */
    @PostMapping("/upload")
    @ResponseBody
    public AjaxResult uploadFile(MultipartFile file) throws Exception {
        try {
            //临时存放地址
            String path = "D:/files/";
            /**
             * 文件夹路径
             */
            File folder = new File(path);
            /**
             * 当文件夹不存在时
             */
            if (!folder.exists()) {
                /**
                 * 创建文件夹
                 */
                folder.mkdirs();
            }
            // 上传文件路径
            // 上传并返回新文件名称
            String fileName = FileUploadUtils.upload(path, file);
            /**
             * ajax存储信息返回前台
             */
            AjaxResult ajax = AjaxResult.success();
            ajax.put("newFileName", FileUtils.getName(fileName));
            ajax.put("originalFilename", file.getOriginalFilename());
            /**
             * 存储word文档内容
             */
            String content = "";
            /**
             * 获取当前时间
             */
            Date date = new Date();
            /**
             * 存储月份并计算，小于10时，加0
             */
            String month = (date.getMonth() + 1) < 10 ? "0" + (date.getMonth() + 1) : "" + (date.getMonth() + 1);
            /**
             * 存储当月第几天天并计算，小于10时，加0
             */
            String day = (date.getDate()) < 10 ? "0" + (date.getDate()) : "" + (date.getDate());
            /**
             * 声明空map存储信息
             */
            Map map = new HashMap();
            /**
             * 调用方法进行获取文件内容
             */
            map = getContentDocxToHtml(path + (1900 + date.getYear()) + "/" + month + "/" + day + "/" + FileUtils.getName(fileName));
            /**
             * 获取文档内容并存入
             */
            content = map.get("content").toString();
            /**
             * 返回前台信息
             */
            ajax.put("content", content);
            return ajax;
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 通用上传请求（多个）
     */
    @PostMapping("/uploads")
    @ResponseBody
    public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception
    {
        try
        {
            // 上传文件路径
            String filePath = RuoYiConfig.getUploadPath();
            List<String> urls = new ArrayList<String>();
            List<String> fileNames = new ArrayList<String>();
            List<String> newFileNames = new ArrayList<String>();
            List<String> originalFilenames = new ArrayList<String>();
            for (MultipartFile file : files)
            {
                // 上传并返回新文件名称
                String fileName = FileUploadUtils.upload(filePath, file);
                String url = serverConfig.getUrl() + fileName;
                urls.add(url);
                fileNames.add(fileName);
                newFileNames.add(FileUtils.getName(fileName));
                originalFilenames.add(file.getOriginalFilename());
            }
            AjaxResult ajax = AjaxResult.success();
            ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER));
            ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER));
            ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER));
            ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER));
            return ajax;
        }
        catch (Exception e)
        {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 本地资源通用下载
     */
    @GetMapping("/download/resource")
    public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
            throws Exception
    {
        try
        {
            if (!FileUtils.checkAllowDownload(resource))
            {
                throw new Exception(StringUtils.format("资源文件({})非法，不允许下载。 ", resource));
            }
            // 本地资源路径
            String localPath = RuoYiConfig.getProfile();
            // 数据库资源地址
            String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX);
            // 下载名称
            String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            FileUtils.setAttachmentResponseHeader(response, downloadName);
            FileUtils.writeBytes(downloadPath, response.getOutputStream());
        }
        catch (Exception e)
        {
            log.error("下载文件失败", e);
        }
    }


    /**
     * 获取正文文件内容，docx方法
     *
     * @param path
     * @return
     */
    public Map<String, String> getContentDocxToHtml(String path) {
        Map<String, String> map = new HashMap();
        // 获取HTML文件流
        StringBuffer content = new StringBuffer("");
        String htmlPath = "D://files//html//"+path.substring(path.lastIndexOf("/"),path.lastIndexOf("_"))+".html";
        try {
            //文档类流存储html信息
            Document doc = new Document();
            //加载文档数据（内容及格式）
            doc.loadFromFile(path);
            //存储html文件
            doc.saveToFile(htmlPath, FileFormat.Html);
            //结束doc文档流
            doc.dispose();
            //读取流读取html代码信息，转为utf-8
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    new FileInputStream(new File(htmlPath)), "utf-8"));
            //循环读取
            while (br.ready()) {
                //逐行读取信息
                content.append(br.readLine());
            }
            //关闭读取流
            br.close();
            //删除html文件及删除html文件夹
//            delFolder("D://桌面//files//html");
        } catch (Exception e) {
            /**
             * 输出错误信息
             */
            e.printStackTrace();
        } finally {
            //判断警告标识
            //使用Spire.Doc生成文档后会自动生成的标识
            if (content.toString().indexOf("Evaluation Warning: The document was created with Spire.Doc for JAVA.") > -1) {
                //去除警告标识语句
                content = new StringBuffer(content.toString().replace("Evaluation Warning: The document was created with Spire.Doc for JAVA.", ""));
            }
            //赋值内容
            map.put("content", content.toString());
        }
        //返回数据
        return map;
    }

    /**
     * 删除本地临时文件
     *
     * @param file
     */
    public void delteTempFile(File file) {
        //文件不为空时
        if (file != null) {
            //加载文件信息
            File del = new File(file.toURI());
            //本地磁盘删除
            del.delete();
        }
    }

    /**
     * 删除文件夹下的所有文件
     * @param path
     * @return
     */
    public static boolean delAllFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return flag;
        }
        if (!file.isDirectory()) {
            return flag;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件
                delFolder(path + "/" + tempList[i]);// 再删除空文件夹
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 删除文件夹
     * @param folderPath
     */
    public static void delFolder(String folderPath) {
        try {
            delAllFile(folderPath); // 删除完里面所有内容
            String filePath = folderPath;
            filePath = filePath.toString();
            File myFilePath = new File(filePath);
            myFilePath.delete(); // 删除空文件夹
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
